package com.hh.controller;

import com.hh.component.FilePathBase;
import com.hh.pojo.ImageObj;
import com.hh.pojo.MessageModel;
import com.hh.pojo.Post;
import com.hh.pojo.User;
import com.hh.service.PostReplyService;
import com.hh.service.PostService;
import org.apache.ibatis.annotations.Delete;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("post")
//@CrossOrigin(origins = "http://localhost:8080",maxAge = 3600)//解决跨域访问
public class PostController {

    @Autowired
    private PostService postService;

    @Autowired
    private PostReplyService prService;

    /*收藏帖子*/
    @GetMapping("cltPost")
    public MessageModel cltPost(HttpServletRequest request, @RequestParam("postId") int postId){
        return postService.collect(getCuserUname(request), postId);
    }
    /*取收藏帖子*/
    @GetMapping("cancelClt")
    public MessageModel cancelClt(HttpServletRequest request, @RequestParam("postId") int postId){
        return postService.cancelClt(getCuserUname(request), postId);
    }

    /*点赞帖子*/
    @GetMapping("sbcPost")
    public MessageModel sbcPost(HttpServletRequest request, @RequestParam("postId") int postId){
        return postService.subscribe(getCuserUname(request), postId);
    }
    /*取消点赞帖子*/
    @GetMapping("cancelSbc")
    public MessageModel cancelSbc(HttpServletRequest request, @RequestParam("postId") int postId){
        return postService.cancelSbc(getCuserUname(request), postId);
    }

    /**
     * 置顶帖子
     * @param postId 要置顶的帖子id
     * @param operateType 1 置顶   0取消置顶  默认为1 -- 置顶
     * @return  置顶（或取消置顶） 结果
     */
    @GetMapping("/admin/setTopPost")
    public MessageModel setTopPost(@RequestParam("postId") int postId, @RequestParam(value = "type", required = false, defaultValue = "1") Integer operateType ){
        return postService.setTopPost(postId, operateType);
    }

    /*获取当前登录用户的用户名， 若未登录 则返回null*/
    private String getCuserUname(HttpServletRequest request){
        User user = UserController.getCurrentUser(request);
        return (user == null) ? null:user.getUname();
    }

    /*前端（首页）点击帖子链接 查看帖子详情  将帖子浏览数++*/
    @PostMapping("addPostViewNum")
    public MessageModel addPostViewNum(@RequestParam("postId") int postId){
        return postService.viewPost(postId);
    }

    /*检查  传过来的postId 是否对应一篇帖子（非私密）*/
    @GetMapping("checkPostValid/{postId}")
    public MessageModel checkPostValid(@PathVariable("postId") int postId){
        MessageModel rs = new MessageModel(200, "帖子编号有效！");
        try {
            if (postService.getPostInfoById(postId) == null){
                rs.setResult_code(309);
                rs.setMsg("该编号对应的帖子不存在！");
            }
        }catch (Exception e){
            rs.setResult_code(303);
            rs.setMsg("数据库查询发生异常！ -- 303");
        }

        return rs;
    }

    /*获取帖子详情信息*/
    @GetMapping("getPostInfo")
    public Map<String, Object> getPostInfo(HttpServletRequest request, HttpServletResponse response,
                                        @RequestParam(name = "postId", required = true) int postId) throws IOException, ServletException {
        Map<String, Object> map = new HashMap<>();
        MessageModel rs = new MessageModel(200, "帖子信息获取成功！");

        try {
            //获取当前登录用户信息
            User currentUser = UserController.getCurrentUser(request);
            String uname = (currentUser == null) ? null:currentUser.getUname();  // 如果用户未登录 则该值为null
            map.put("user", currentUser);

            //获取帖子信息
            Post postInfoById = postService.getPostInfoById(postId);
            if (postInfoById == null){ // 没查询到 有关的帖子信息
                /*
                本来是想 throw 一个异常 然后在catch里重定向到前端的,
                可是它报错跨域问题，不能从前端访问后端，再后端重定向回前端
                * */
                throw new NullPointerException("帖子不存在或已被删除！");
            }

            // 判断是否有权限访问该贴
            if (!postService.checkViewAuthority(postInfoById, currentUser)){
                rs.setResult_code(609);
                rs.setMsg("您暂无权限查看该帖子！");
                map.put("rs", rs);
                return map;
            }

            //获取   当前登录用户   和   该帖子  的关系（点赞、收藏、贴吧的加入关系）
            Map<String, Boolean> userPostRvc = postService.getUserPostRvc(uname, postId);
            //获取   当前登录用户   和   该帖子评论列表  的点赞关系
            Map<Integer, Boolean> userPRSbcRvc = prService.getUserPRSbcRvc(uname, postInfoById.getReplies());

            map.put("post", postInfoById);
            map.put("rvc", userPostRvc);
            map.put("prRvcMap", userPRSbcRvc);
        } catch (NullPointerException e){
            rs.setResult_code(309);
            rs.setMsg("抱歉，帖子不存在或已被删除！");
        } catch (Exception e){
            rs.setResult_code(303);
            rs.setMsg("帖子信息获取发生异常！！！");
            e.printStackTrace();
        }

        map.put("rs", rs);
        return map;
    }

    @Test
    public void testMap(){
        Map<String, Object> map = new HashMap<>();

        map.put("n1", 1);
        {
            Integer n2 = 2;
            map.put("n2", 2);
        }
        System.out.println("n1:" + map.get("n1"));
        System.out.println("n2:" + map.get("n2"));
    }

    @RequestMapping("uploadImage")
    public Map<String, Object> uploadImage(){
        Map<String, Object> map = new HashMap<>();
        ArrayList<ImageObj> imageObjs = new ArrayList<>();

        imageObjs.add(new ImageObj("https://dss2.bdstatic.com/lfoZeXSm1A5BphGlnYG/skin/117.jpg?2",
                                    "百度首页背景",
                                    "https://dss2.bdstatic.com/lfoZeXSm1A5BphGlnYG/skin/117.jpg?2"));

        map.put("errno", 0); //没有错误
        map.put("data", imageObjs);
        return map;
    }

    /*获取当前登录用户加加入的贴吧  以及当前登录用户*/
    /*
        返回：MessageModel
        result_code
        605  未登录
        607  加入贴吧数为0
        303  数据库插入发生异常
        200  正常获取贴吧且贴吧数不为0
    * */
    @GetMapping("getUserBar")
    public Map<String, Object> initPublish(HttpServletRequest request){
        User user = (User)request.getSession().getAttribute("user");
        HashMap<String, Object> map = new HashMap<>();

        if (user == null){//未登录
            map.put("rs", new MessageModel(605, "当前未登录，请登录后进行发帖！"));
            return map;
        }
        //用户已登录
        return postService.getUserBarList(user);
    }


    /**
     *  发布(增加) 一篇帖子
     * @param files 前端上传的文件列表
     * @param barId  帖子对应的贴吧id
     * @param title 帖子标题
     * @param content 帖子内容
     * @return 发布结果
     */
    @PostMapping("publish")
    public MessageModel publishPost(@Nullable @RequestParam("files") MultipartFile[] files, @RequestParam("barId") int barId,
                                    @RequestParam("title") String title, @RequestParam("content") String content,
                                    @RequestParam("pure_content") String pure_content, HttpServletRequest request){
        User user = (User) request.getSession().getAttribute("user");  //获取当前登录用户
//        String path = request.getServletContext().getRealPath("/static/images/postImage/"); //存放帖子图片的地址
        String path = FilePathBase.baseUrl + FilePathBase.postImage; //存放帖子图片的地址

        System.out.println("【path  /static/images/postImage/】 :" + path);
//        return null;
        return postService.publishPost(user, files, barId, title, content, pure_content, path);
    }

    /*
        函数功能： 根据搜索关键字搜索帖子 根据排序方式对搜索结果进行排序 根据页码及页大小对搜索帖子结果作分页
        函数参数：index: 所要的页码 pageSize：页大小  word搜索关键字 sortType：排序方式
        返回值：返回map，rs表示查询结果， list表示对应搜索结果下排序后的 对应页的帖子列表，
    */
    @GetMapping("getSearchListByPage")
    public Map<String, Object> getSearchedPostsByPage(@RequestParam("index") int index, @RequestParam("pageSize") int pageSize,
                                                      @RequestParam("word") String word, @RequestParam("sortType") String sortType) throws ServletException, IOException {
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
        Map<String, Object> map = new HashMap<>();

        System.out.println("word:" + word);
        map.put("index", index);
        map.put("pageSize", pageSize);
        map.put("word", word);
        map.put("accordingTo", sortType);

        return postService.getSearchedListByPage(map);
    }

    /*
        函数功能： 根据搜索关键字搜索帖子 根据排序方式对搜索结果进行排序 根据页码及页大小对搜索帖子结果作分页  某个用户的帖子
        函数参数：index: 所要的页码 pageSize：页大小  wordL搜索关键字 sortType：排序方式 uname：用户名
                    listType：0 普通  1 收藏  2 私密
        返回值：返回map，rs表示查询结果， list表示对应搜索结果下排序后的 对应页的帖子列表，
    */
    @GetMapping("getPostsByUser")
    public Map<String, Object> getUserSearchedPostsByPage(@RequestParam("index") int index, @RequestParam("pageSize") int pageSize,
                                                      @RequestParam("word") String word, @RequestParam("sortType") String sortType,
                                                          @RequestParam("uname") String uname, @RequestParam("listType") int listType,
                                                          HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
        Map<String, Object> map = new HashMap<>();

        map.put("index", index);
        map.put("pageSize", pageSize);
        map.put("word", word);
        map.put("accordingTo", sortType);
        map.put("uname", uname);
        map.put("userListType", listType);
        map.put("request", request);
        map.put("response", response);

        return postService.getSearchedListByPage(map);
    }

    /*
        函数功能： 根据搜索关键字搜索帖子 根据排序方式对搜索结果进行排序 根据页码及页大小对搜索帖子结果作分页  某个贴吧的帖子
        函数参数：index: 所要的页码 pageSize：页大小  word 搜索关键字 sortType：排序方式 barId：贴吧id
        返回值：返回map，rs表示查询结果， list表示对应搜索结果下排序后的 对应页的帖子列表，
    */
    @GetMapping("getTopPosts")
    public Map<String, Object> getTopPostsByBar(@RequestParam("barId") int barId){
        return postService.getTopPostsByBar(barId);
    }

    /*
        函数功能： 根据搜索关键字搜索帖子 根据排序方式对搜索结果进行排序 根据页码及页大小对搜索帖子结果作分页  某个贴吧的帖子
        函数参数：index: 所要的页码 pageSize：页大小  word 搜索关键字 sortType：排序方式 barId：贴吧id
        返回值：返回map，rs表示查询结果， list表示对应搜索结果下排序后的 对应页的帖子列表，
    */
    @GetMapping("getPostsByBar")
    public Map<String, Object> getBarSearchedPostsByPage(@RequestParam("index") int index, @RequestParam("pageSize") int pageSize,
                                                      @RequestParam(value = "word", required = false) String word,  @RequestParam(value = "searchType", required = false) Integer searchType,
                                                      @RequestParam("sortType") String sortType,
                                                      @RequestParam("barId") int barId) throws ServletException, IOException {
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
//        Map<String, Object> map = new HashMap<>();
//
//        map.put("index", index);
//        map.put("pageSize", pageSize);
//        map.put("word", word);
//        map.put("accordingTo", sortType);
//        map.put("barId", barId);

        return getPostList(index, pageSize, sortType, word, searchType, barId, null, -1, null, null);
    }

    /**
     * 根据 你给的参数（包括用户和贴吧，所有情况）  来获取 对应的 帖子列表
     * @param index
     * @param pageSize
     * @param sortType 排序方式 字符串  time  reply  view 分别表示 根据时间、回复数、浏览量排序
     * @param word
     * @param searchType 搜索类型  决定 word是 0 -- 帖子id 还是 1 -- 帖子标题
     * @param barId
     * @param uname
     * @param listType 用户帖子0 普通  1 收藏  2 私密
     * @param request  当获取用户帖子时，根据帖子类型要进行身份验证
     * @param response
     * @return
     */
    public Map<String, Object> getPostList(int index, int pageSize, String sortType,
                                           String word, Integer searchType,
                                           Integer barId, String uname, int listType,
                                           HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
        Map<String, Object> map = new HashMap<>();

        /*一般必要传的参数*/
        map.put("index", index);
        map.put("pageSize", pageSize);
        map.put("accordingTo", sortType);
        if (word != null){
            if (searchType != null && searchType == 0 && !"".equals(word)){
                map.put("pid", Integer.parseInt(word));
            }else {
                map.put("word", word);
            }
        }

        /*根据情况传  （不需要的话 传null）*/
        if (barId != null){
            map.put("barId", barId);
        }
        if (uname != null){
            // uname 和 listType 绑定在一起的
            map.put("uname", uname);
            map.put("userListType", listType);
            map.put("request", request);
            map.put("response", response);
        }

        Map<String, Object> list = postService.getSearchedListByPage(map);
        return list;
    }

    // 根据map 获取帖子列表，返回列表条目数。
    // word 为搜索关键字， @Nullable 意为可为空，不加该注解且不传递该参数则会报错(必须传该参数  boolean required() default true;)
    // uname 针对某个用户搜索 如果不是，默认接收到的是字符串 "null" length:4 （注意不是null对象） ， userPostType 默认为0
    // searchType 搜索类型  决定 word是 0 -- 帖子id 还是 1 -- 帖子标题
    @GetMapping("getTotalNum")
    public int getPostListTotalNum(@Nullable @RequestParam("word") String word,
                                   @RequestParam(value = "searchType", required = false) Integer searchType,
                                   @RequestParam(value = "uname", required = false) String uname,
                                   @RequestParam(value = "listType", required = false) Integer userPostType,
                                   @RequestParam(value = "barId", required = false) Integer barId){
        Map<String, Object> map = new HashMap<>();

        // 无论是否针对某用户进行查询，先放到 map，在 mapper sql 中进行统一判断
        map.put("uname", uname);
        map.put("userListType", userPostType);
//        System.out.println("uname:" + uname + "  length:" + uname.length());
//        System.out.println("getTotalNum-- uname:" + uname + ", listType:" + userPostType + " word:" + word);

        if (barId != null){
            map.put("barId", barId);
        }
        if (word != null){
            System.out.println("word不为空！");
            // 只有在 指定了搜索类型且  搜索类型是 0（帖子编号） 时 才 将搜索关进字转为帖子 id 存入map
            if (searchType != null && searchType == 0 && !"".equals(word)){
                map.put("pid", Integer.parseInt(word));
            }else {
                map.put("word", word);
            }
        }
//        System.out.println("searchType:" + (searchType == null));
//        System.out.println("barId:" + (barId == null));
//        System.out.println("barId:" + "  |  " + barId.toString());
//        System.out.println("isNull:" + barId == null);

        return postService.getTotalNum(map);
    }

    /*根据帖子总回复数 分页查询帖子信息 pageSize 和 index 分别表示每页大小和页码*/
    @GetMapping("getListByReply")
    public Map<String, Object> getPostsByReply(@RequestParam("index") int index, @RequestParam("pageSize") int pageSize){
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
//        try {
//            TimeUnit.SECONDS.sleep(1);
//            System.out.println("沉睡完毕");
//        } catch (InterruptedException e) {
//            System.out.println("沉睡发生异常");
//            e.printStackTrace();
//        }
        return postService.getListByReply(index, pageSize);
    }

    /*根据 帖子发表时间  查询帖子信息*/
    @GetMapping("getListByTime")
    public Map<String, Object> getPostsByTime(int index, int pageSize){
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
        return postService.getListByTime(index, pageSize);
    }

    /*根据帖子总回复数 分页查询帖子信息 pageSize 和 index 分别表示每页大小和页码*/
    @GetMapping("getListBySortType")
    public Map<String, Object> getPostsBySortType(@RequestParam("index") int index, @RequestParam("pageSize") int pageSize,
                                                  @RequestParam("sortType") String accordingTo){
        /*注意， 此时返回的 帖子图片   是多张图片以空格分隔  结合而成的字符串*/
        /*转发到前端再进行处理*/
//        try {
//            TimeUnit.SECONDS.sleep(1);
//            System.out.println("沉睡完毕");
//        } catch (InterruptedException e) {
//            System.out.println("沉睡发生异常");
//            e.printStackTrace();
//        }
        return postService.getListBySortType(index, pageSize, accordingTo);
    }


    /**
     * 删除一篇帖子（该操作可能由管理员  也可能由用户自己发起）
//     * @param uname 帖子所属用户名 // 用于鉴别身份  -- 在拦截器里会用到
     * @param postId 要删除的帖子id
     * @return 返回删除结果 包含状态码和 信息
     */
    @DeleteMapping("/my/del")
    public MessageModel deletePostById(@RequestParam("postId") int postId, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        return postService.deletePostById(request, response, postId);
    };


    /*测试文件接收*/
    @RequestMapping("testFile")
    @ResponseBody
    public String testFile(@RequestParam("files") MultipartFile[] file){
        System.out.println("进入控制器");

        System.out.println("文件数组长度：" + file.length);
        for (MultipartFile file1 : file) {
            System.out.println("文件名：" + file1.getOriginalFilename());
        }
        return "from the server";
    }
}
